package de.dhbw.karlsruhe.picsim.model.memory.impl;

import de.dhbw.karlsruhe.picsim.model.memory.RegisterValue;
import de.dhbw.karlsruhe.picsim.util.Bits;
import de.dhbw.karlsruhe.picsim.util.impl.BitUtilities;
import de.dhbw.karlsruhe.picsim.util.impl.Lengths;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Created by IntelliJ IDEA.
 * User: goesen
 * Date: Apr 14, 2010
 * Time: 10:15:37 AM
 */
public class RegisterValueImpl implements RegisterValue {
    private final Bits delegate;


    @SuppressWarnings({"ConstantConditions"})
    @NotNull
    public static RegisterValue createUnsafe(final int value) {
        return value >= 0 ? createSafe(value % 256) : createUnsafe(256 + value % 256);
    }

    @Nullable
    public static RegisterValue createSafe(final int value) {
        return value >= 0 && value < 256 ? new RegisterValueImpl(value) : null;
    }

    private RegisterValueImpl(final int value) {
        this(BitUtilities.asLeastSignificantBitFirst(value, Lengths.FILE_LENGTH));
    }

    public RegisterValueImpl(final Bits value) {
        if (value.getLength() != Lengths.FILE_LENGTH) {
            throw new IllegalArgumentException(value.toString());
        }
        delegate = BitUtilities.clone(value);
    }

    @Override
    public int getLength() {
        return Lengths.FILE_LENGTH;
    }

    @Override
    public boolean isSet(final int bitNr) {
        return delegate.isSet(bitNr);
    }

    @Override
    public int asInteger() {
        return BitUtilities.fromLeastSignificantBitFirst(delegate);
    }

    @Override
    public String toString() {
        return "de.dhbw.karlsruhe.picsim.model.memory.impl.RegisterValueImpl{" +
                "value=" + delegate +
                '}';
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final RegisterValueImpl that = (RegisterValueImpl) o;

        return delegate.equals(that.delegate);

    }

    @Override
    public int hashCode() {
        return delegate.hashCode();
    }
}
